import { useRefValue } from '@gnlab/utils/env-react/hooks'
import { ReactComponent as ThirdAppDefaultIcon } from '@/desktop/assets/third-app-default.svg'
import { ShowThirdApp } from '@/desktop/views/app-center/index/third-app'
import { useStreams } from '@/lib/utils'
import useUIMemory from '@/logics/memory'
import services from '@/services'
import type { ThirdApp } from '@/services/features/third-apps'
import { appCategories } from './apps-definition'

export interface AppCategory {
  id: string
  name: string
  menus: AppMenu[]
}

export interface BaseAppMenu {
  id: string
  name: string
  icon: React.ReactNode
  admin?: boolean | string // 为 true 或 string 代表需要管理员权限，其中 string 是提示信息
  beta?: boolean // 为 true 代表是内测应用
  thirdApp?: ThirdApp // 有值代表是自建应用
}
export interface ModalAppMenu extends BaseAppMenu {
  component: ModalAppComponent
}
export interface PanelAppMenu extends BaseAppMenu {
  component: PanelAppComponent
  panel: true
}
export type AppMenu = ModalAppMenu | PanelAppMenu

export type ModalAppComponent = (props: { open: boolean; onClose: () => void }) => React.ReactNode
export type PanelAppComponent = () => React.ReactNode

export type AppCategoryForSCRM = Pick<AppCategory, 'id' | 'name'> & { menus: AppMenuForSCRM[] }
export type AppMenuForSCRM = Pick<AppMenu, 'id' | 'name'>

/**
 * 记录各 app 的最后开启时间
 */
export function useRecordOpen() {
  const [opened, setOpened] = useUIMemory<Record<string, number>>('app-center-opened', {})
  const openedRef = useRefValue(opened)
  const recordOpen = useCallback(
    (appId: string) => {
      setTimeout(() => setOpened({ ...openedRef.current, [appId]: Date.now() }), 300)
    },
    [setOpened],
  )
  return { opened, recordOpen }
}

/**
 * 返回基础应用列表
 */
export function useCategories() {
  const [rawIsAdmin, thirdApps] = useStreams(
    services.auth.isAdmin$,
    services.features.thirdApps.list,
  )
  const isAdmin = rawIsAdmin ?? false

  const { formatted, allMenus } = useMemo(() => {
    const formatted = [
      ...appCategories.map(category => ({
        ...category,
        menus: category.menus.filter(menu => menu.admin !== true || isAdmin)
      })),
      {
        id: 'third',
        name: '自建应用',
        menus: thirdApps.map(transformThirdApp),
      },
    ]

    const allMenus = formatted.reduce<AppMenu[]>(
      (menus, category) => [...menus, ...category.menus],
      [],
    )

    return { formatted, allMenus }
  }, [isAdmin, thirdApps])

  return { formattedCategories: formatted, allMenus, isAdmin }
}

/**
 * 返回排序过的应用列表
 */
export function useSortedCategories(formattedCategories: AppCategory[], allMenus: AppMenu[]) {
  const { opened } = useRecordOpen()
  const sorted = useMemo(() => {
    const sort = (a: AppMenu, b: AppMenu) => (opened[b.id] ?? 0) - (opened[a.id] ?? 0)
    const sorted = [...formattedCategories]
    sorted.unshift({
      id: 'all',
      name: '全部应用',
      menus: [...allMenus].sort(sort),
    })
    return sorted
  }, [formattedCategories, allMenus, opened])
  return sorted
}

export function transformThirdApp(thirdApp: ThirdApp): AppMenu {
  return {
    id: 'third-' + thirdApp.id,
    icon: thirdApp.icon ? <img src={thirdApp.icon} loading="lazy" /> : <ThirdAppDefaultIcon />,
    name: thirdApp.name,
    component(props) {
      return <ShowThirdApp thirdApp={thirdApp} {...props} />
    },
    thirdApp,
  }
}
